import java.io.*;
import java.util.BitSet;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 *
 * @author Jun
 * @date 2019/3/23
 */
public class Main {

    /**
     * file1和file2分别需要用两个bitSet存储正负数是否出现过;
     * 另外，由于bitSet size最大值为Integer.MAX_VALUE，
     * 所以需要单独处理3个边界值：Integer.MAX_VALUE，Integer.MIN_VALUE, Integer.MIN_VALUE + 1
     */
    static BitSet file1BitSetPositive = new BitSet(Integer.MAX_VALUE);
    static BitSet file1BitSetNegative = new BitSet(Integer.MAX_VALUE);
    static AtomicBoolean file1MinValue = new AtomicBoolean(false);
    static AtomicBoolean file1MaxValue = new AtomicBoolean(false);
    static AtomicBoolean file1SecondMinValue = new AtomicBoolean(false);

    static BitSet file2BitSetPositive = new BitSet(Integer.MAX_VALUE);
    static BitSet file2BitSetNegative = new BitSet(Integer.MAX_VALUE);
    static AtomicBoolean file2MinValue = new AtomicBoolean(false);
    static AtomicBoolean file2MaxValue = new AtomicBoolean(false);
    static AtomicBoolean file2SecondMinValue = new AtomicBoolean(false);

    /**
     * 求文件整数交集
     *
     * @param sourceFilePath1 源文件1
     * @param sourceFilePath2 源文件2
     * @param outputFilePath 目标文件
     * @return
     */
    public static void intersect(String sourceFilePath1, String sourceFilePath2, String outputFilePath) {
        try {
            BufferedReader reader1 = new BufferedReader(new FileReader(new File(sourceFilePath1)));
            writeBitSet(file1BitSetPositive, file1BitSetNegative, file1MinValue, file1MaxValue, file1SecondMinValue, reader1);

            BufferedReader reader2 = new BufferedReader(new FileReader(new File(sourceFilePath2)));
            writeBitSet(file2BitSetPositive, file2BitSetNegative, file2MinValue, file2MaxValue, file2SecondMinValue, reader2);

            File file = new File(outputFilePath);
            if (file.exists()) {
                file.delete();
            }

            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(outputFilePath, true), "UTF-8"));

            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                if (file1BitSetPositive.get(i) && file2BitSetPositive.get(i)) {
                    writer.write(String.valueOf(i));
                    writer.newLine();
                }
                if (file1BitSetNegative.get(i) && file2BitSetNegative.get(i)) {
                    writer.write(String.valueOf(-i));
                    writer.newLine();
                }
            }

            // 单独处理3个边界值
            if (file1MinValue.get() && file2MinValue.get()) {
                writer.write(String.valueOf(Integer.MIN_VALUE));
                writer.newLine();
            }

            if (file1MaxValue.get() && file2MaxValue.get()) {
                writer.write(String.valueOf(Integer.MAX_VALUE));
                writer.newLine();
            }

            if (file1SecondMinValue.get() && file2SecondMinValue.get()) {
                writer.write(String.valueOf(Integer.MIN_VALUE + 1));
                writer.newLine();
            }
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 遍历文件，写入bitSet
     *
     * @param bitSetPositive 正整数
     * @param bitSetNegative 负整数
     * @param minValue 最小值
     * @param maxValue 最大值
     * @param secondMinValue 次小值
     * @param reader 文件reader
     */
    private static void writeBitSet(BitSet bitSetPositive, BitSet bitSetNegative, AtomicBoolean minValue, AtomicBoolean maxValue, AtomicBoolean secondMinValue, BufferedReader reader) {
        String tempString;
        try {
            while ((tempString = reader.readLine()) != null) {
                Integer value = Integer.valueOf(tempString);
                if (value == Integer.MIN_VALUE) {
                    minValue.set(true);
                } else if (value == Integer.MAX_VALUE) {
                    maxValue.set(true);
                } else if (value == Integer.MIN_VALUE + 1) {
                    secondMinValue.set(true);
                } else if (value >= 0) {
                    bitSetPositive.set(value);
                } else {
                    bitSetNegative.set(-value);
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化源文件
     */
    public static void initFile(String sourceFilePath1, String sourceFilePath2){
        try {
            BufferedWriter writer1 = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(sourceFilePath1, true), "UTF-8"));

            BufferedWriter writer2 = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(sourceFilePath2, true), "UTF-8"));
            ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
            for (int j=0; j< 100; j++) {
                for (int i = 0; i < 100000000; i++) {
                    writer1.write(String.valueOf(threadLocalRandom.nextInt(10000000)));
                    writer1.newLine();
                    writer2.write(String.valueOf(threadLocalRandom.nextInt(10000000)));
                    writer2.newLine();
                }
            }
            writer1.close();
            writer2.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 第一次跑，先初始化两个源文件
        //initFile("D:\\test\\s1.txt", "D:\\test\\s2.txt");
        intersect("D:\\test\\s1.txt", "D:\\test\\s2.txt", "D:\\test\\o1.txt");

    }
}
